package com.czn.datasourcesync.service;

import com.czn.datasourcesync.model.CopyTableTask;
import com.czn.datasourcesync.model.SourceDataSource;
import com.czn.datasourcesync.model.TargetDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author Zenan Chen
 * @date 2023/9/14 16:10
 */
@Service
public class SyncDataSourceServiceImpl implements SyncDataSourceService {

    private static final Logger log = LoggerFactory.getLogger(SyncDataSourceServiceImpl.class);
    @Autowired
    private SourceDataSource sourceDataSource;
    @Autowired
    private TargetDataSource targetDataSource;

    @Value("${insert.batch.num:10000}")
    private Integer size;
    @Value("${thread.core.num:3}")
    private Integer coreNum;


    @Scheduled(cron = "${sync.cron}")
    @Override
    public void sync() {
        String sourceURL = sourceDataSource.getUrl();
        String sourceUser = sourceDataSource.getUser();
        String sourcePassword = sourceDataSource.getPassword();

        String targetURL = targetDataSource.getUrl();
        String targetUser = targetDataSource.getUser();
        String targetPassword = targetDataSource.getPassword();

        try (Connection conn1 = DriverManager.getConnection(sourceURL, sourceUser, sourcePassword); Connection conn2 = DriverManager.getConnection(targetURL, targetUser, targetPassword); ResultSet tables = conn1.getMetaData().getTables(null, null, null, new String[]{"TABLE"})) {
            List<String> tableNames = new ArrayList<>();
            while (tables.next()) {
                String tableName = tables.getString("TABLE_NAME");
                tableNames.add(tableName);
            }
            ExecutorService executorService = Executors.newFixedThreadPool(coreNum);
            for (String tableName : tableNames) {
                log.info("-----------------> tableName：{}", tableName);
                CopyTableTask copyTableTask = new CopyTableTask(tableName, sourceDataSource, targetDataSource, size);
                executorService.submit(copyTableTask, tableName);
            }
            executorService.shutdown();
        } catch (Exception e) {
            log.error("SQLException: {}", e);
        }
    }
}
